package com.xiaoshuidi.cloud.module.contract.service.approval;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoshuidi.cloud.framework.common.pojo.CommonResult;
import com.xiaoshuidi.cloud.module.contract.controller.admin.approval.vo.ContractApprovalCreateReqVO;
import com.xiaoshuidi.cloud.module.contract.controller.admin.approval.vo.ContractApprovalReqVO;
import com.xiaoshuidi.cloud.module.contract.controller.admin.approval.vo.ContractApprovalUpdateReqVO;
import com.xiaoshuidi.cloud.module.contract.convert.approval.ContractApprovalConvert;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.approval.ContractApprovalConfigDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.approval.ContractApprovalDO;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.approval.ContractApprovalConfigMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.approval.ContractApprovalMapper;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.ApartmentApi;
import com.xiaoshuidi.cloud.module.rooms.api.apartment.dto.ApartmentListDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.contract.enums.ErrorCodeConstants.*;

/**
 * 合同配置房间 Service 实现类
 *
 * @author 合房租赁
 */
@Service
@Slf4j
public class ContractApprovalServiceImpl implements ContractApprovalService {

    @Resource
    private ContractApprovalMapper approvalMapper;
    @Resource
    private ContractApprovalConfigMapper contractApprovalConfigMapper;

    @Resource
    private ApartmentApi apartmentApi;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createRooms(ContractApprovalReqVO req) {
        Long approvalId = req.getApprovalId();
        List<Long> apartmentIds = req.getApartmentIds();
        //是否配置工作流
        ContractApprovalConfigDO configDO = getContractApprovalConfigDO(approvalId);
        log.info("审批配置:{}",JSONObject.toJSONString(configDO));
        //删除工作流配置房源
        delApproval(approvalId);
        //查询已经存在的 同一类型的审批流已经配置了
        getListCommonResult(req,configDO.getType(), apartmentIds);
        //新绑定房源的 信息
        CommonResult<List<ApartmentListDto>> listCommonResult=apartmentApi.listByIds(apartmentIds);
        Map<Long,ApartmentListDto> map=new HashMap<>();
        if (listCommonResult.isSuccess()) {
            map =  listCommonResult.getCheckedData().stream().collect(Collectors.toMap(ApartmentListDto::getId,v->v));
        }

        List<ContractApprovalDO> contractApprovalDOList=new ArrayList<>();
        if (CollectionUtils.isNotEmpty(apartmentIds)) {
            for (Long apartmentId : apartmentIds) {
                ApartmentListDto apartmentListDto = map.get(apartmentId);
                if (apartmentListDto==null) {
                    throw exception(APARTMENT_NOT_EXIST);
                }
                ContractApprovalDO contractApprovalDOBuilder = ContractApprovalDO.builder().approvalId(approvalId)
                        .apartmentId(apartmentListDto.getId())
                        .apartmentName(apartmentListDto.getName())
                        .type(configDO.getType())
                        .isOpen(1)
                        .build();
                contractApprovalDOList.add(contractApprovalDOBuilder);
            }
            //  根据类型和租户id 查询是否存在记录
            approvalMapper.insertBatch(contractApprovalDOList);
        }
        String apartmentNames = contractApprovalDOList.stream().map(ContractApprovalDO::getApartmentName).collect(Collectors.joining(","));
        configDO.setApartmentNames(StringUtils.isBlank(apartmentNames)?null:apartmentNames);
        contractApprovalConfigMapper.updateById(configDO);
    }

    @NotNull
    private ContractApprovalConfigDO getContractApprovalConfigDO(Long approvalId) {
        ContractApprovalConfigDO configDO = contractApprovalConfigMapper.selectById(approvalId);
        if (configDO==null) {
            throw exception(APPROVAL_NOT_EXISTS);
        }
        if (StringUtils.isBlank(configDO.getMark())) {
            throw exception(PLEASE_SET_APPROVAL);
        }
        return configDO;
    }

    @Nullable
    private void getListCommonResult(ContractApprovalReqVO req,String type, List<Long> apartmentIds) {
        if (CollectionUtils.isNotEmpty(apartmentIds)) {
            LambdaQueryWrapper<ContractApprovalDO> wrapper=new LambdaQueryWrapper<>();
            wrapper.in(ContractApprovalDO::getApartmentId, apartmentIds)
                    .eq(ContractApprovalDO::getType,type)
                   .ne(ContractApprovalDO::getApprovalId, req.getApprovalId())
            ;
            List<ContractApprovalDO> contractApproval = approvalMapper.selectList(wrapper);
            if (CollectionUtils.isNotEmpty(contractApproval)) {
                throw exception(APPROVAL_ROOM_CONFIGURED);
            }
        }
    }

    /**
    * 删除审批流关联房源
    * */
    private void delApproval(Long approvalId) {
        LambdaQueryWrapper<ContractApprovalDO> delWrapper=new LambdaQueryWrapper<>();
        delWrapper.eq(ContractApprovalDO::getApprovalId, approvalId);
        //删除以前的配置项
        approvalMapper.delete(delWrapper);
    }

    @Override
    public String getByRoomIdAndMark(Long apartmentId,String type) {
        String mark = approvalMapper.getByRoomIdAndMark(apartmentId, type);
        return mark;
    }

    @Override
    public Long createApproval(ContractApprovalCreateReqVO createReqVO) {
        // 插入
        ContractApprovalDO approval = ContractApprovalConvert.INSTANCE.convert(createReqVO);
        approvalMapper.insert(approval);
        // 返回
        return approval.getId();
    }

    @Override
    public void updateApproval(ContractApprovalUpdateReqVO updateReqVO) {
        // 校验存在
        validateApprovalExists(updateReqVO.getId());
        // 更新
        ContractApprovalDO updateObj = ContractApprovalConvert.INSTANCE.convert(updateReqVO);
        approvalMapper.updateById(updateObj);
    }

    @Override
    public void deleteApproval(Long id) {
        // 校验存在
        validateApprovalExists(id);
        // 删除
        approvalMapper.deleteById(id);
    }

    private void validateApprovalExists(Long id) {
        if (approvalMapper.selectById(id) == null) {
            throw exception(APPROVAL_ROOM_NOT_EXISTS);
        }
    }

    @Override
    public ContractApprovalDO getApproval(Long id) {
        return approvalMapper.selectById(id);
    }

    @Override
    public List<ContractApprovalDO> getApprovalList(Collection<Long> ids) {
        return approvalMapper.selectBatchIds(ids);
    }

    /**
    * 审批流id查询绑定的公寓
    * */
    @Override
    public List<Long> getApartmentIdsListByApprovalId(Long id) {
        LambdaQueryWrapper<ContractApprovalDO> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(ContractApprovalDO::getApprovalId,id);
        List<ContractApprovalDO> contractApprovalDOList = approvalMapper.selectList(wrapper);
        List<Long> collect = contractApprovalDOList.stream().map(ContractApprovalDO::getApartmentId).collect(Collectors.toList());
        return collect;
    }

}
